package com.hhsjdesign.dynamicui.core.widgetimpl

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.RoundRectShape
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.LinearLayout
import com.hhsjdesign.dynamicui.interfaces.IBgLoader
import com.hhsjdesign.dynamicui.core.property.ShapeProperty
import com.hhsjdesign.dynamicui.core.widgetdata.WidgetData
import com.hhsjdesign.dynamicui.core.property.WidgetSpecProperty
import android.graphics.ColorMatrixColorFilter

import android.graphics.ColorMatrix
import com.hhsjdesign.dynamicui.core.widgetdata.WidgetTypeConst
import com.hhsjdesign.dynamicui.reddot.RedDotFrameLayout
import com.hhsjdesign.dynamicui.utils.*


/**
 * layout
 * 1，创建自己视图
 * 2，创建子组件视图
 *
 * setSize
 * 3，设置自己尺寸和子组件视图尺寸
 *
 * loadData
 * 4，加载自己（业务组件的时候可能需要创建子组件）
 * 5，加载子组件（确切的业务数据与视图的实例）
 */
/**
 * @param context activity
 * @param widgetData
 */
abstract class IWidget(
    val context: Context,
    var widgetData: WidgetData
) :
    View.OnAttachStateChangeListener, IBgLoader {

    //组件id,必须的
    var widgetId: String? = null

    //父组件
    var parentWidget: IWidget? = null

    //自身布局
    var contentView: View? = null

    var realContentView: FrameLayout? = null

    //一级子组件
    var childList: MutableList<IWidget>? = null

    lateinit var shapeProperty: ShapeProperty

    //是否可重新创建
    var canRemakeView = false

    //是否需要重建,当需要的时候,contentView就不能为空
    var needMakeView = true

    //需要远端调用的(net 或者 local都是远端,只有直接带过来的才不是)
    var dataCaller: DataCaller<*>? = null

    init {
        if (
            widgetData.dataSource == WidgetData.SOURCE_TYPE_DYNAMIC && widgetData.business != null
        ) {
            dataCaller = DataCallerFactory.makeDataCaller(this.widgetData.business!!)
        }
        transformShapeProperty()
    }

    /**
     * 解析视图参数用于background
     */
    private fun transformShapeProperty() {
        shapeProperty = if (widgetData.viewProperty != null)
            widgetData.viewProperty!!.toShapeProperty()
        else ShapeProperty()
    }


    //1.创建视图
    open fun makeWidget() {
        //1，根据组件类型确定组件的大布局，也就是contentView
        //2，根据子视图类型确定子视图布局，除了itemView
        if (needMakeView &&
            (contentView == null || canRemakeView)
        ) {
            realContentView = RedDotFrameLayout(context).apply {
                this.name = widgetData.name
            }
            widgetData.specProperty?.let {
                contentView = createMainView(it)
                realContentView!!.addView(contentView)
            }
        }


        if (contentView != null) {
            Log.e("hhsjh", "创建视图 ${this.javaClass.name} 成功")
        } else {
            Log.e("hhsjh", "创建视图 ${this.javaClass.name} 失败")
        }
        contentView ?: return
        //3，添加移除和添加的监听
        contentView!!.addOnAttachStateChangeListener(this)
        //4，设置自身大小
        layout(shapeProperty, widgetData.parentLayoutType ?: WidgetTypeConst.LAYOUT_LINEAR_VERTICAL)
        //5，分发子视图操作makeView
        childMakeView()
    }

    //更新组件
    open fun updateWidget(widgetData: WidgetData) {
        if (this.widgetData == widgetData) {
            //如果不需要
            return
        }
        this.widgetData = widgetData

        //1，判断是否需要更换主视图，如果需要，则将全部重来
        if (this.widgetData.type != widgetData.type) {
            canRemakeView = true
            makeWidget()
        }
        if (parentWidget?.contentView != null) {
            attachToViewParent(parentWidget?.contentView as ViewGroup)
        }

        loadData()
    }

    //创建自生视图
    abstract fun createMainView(specProperty: WidgetSpecProperty): View

    //设置视图的宽高，和父组件有关系，如果父组件是 layout，将注意Param，如果不是，就无所谓
    open fun layout(
        property: ShapeProperty,
        parentType: String
    ) {
        //父布局linearLayout
        if (widgetData.parentLayoutType == WidgetTypeConst.LAYOUT_LINEAR_VERTICAL) {
            realContentView?.layoutParams = LinearLayout.LayoutParams(
                widgetData.viewProperty!!.size[1], widgetData.viewProperty!!.size[3]
            ).apply {
                //比例
                if (widgetData.viewProperty!!.size[2] == 1) {
                    this.weight = widgetData.viewProperty!!.size[3].toFloat()
                    this.height = 0
                }
            }
        } else if (widgetData.parentLayoutType == WidgetTypeConst.LAYOUT_LINEAR_HORIZONTAL) {
            realContentView?.layoutParams = LinearLayout.LayoutParams(
                widgetData.viewProperty!!.size[1], widgetData.viewProperty!!.size[3]
            ).apply {
                //比例
                if (widgetData.viewProperty!!.size[0] == 1) {
                    this.weight = widgetData.viewProperty!!.size[1].toFloat()
                    this.width = 0
                }
            }
        }
        //父布局frameLayout
        else if (widgetData.parentLayoutType == WidgetTypeConst.LAYOUT_FRAME) {
            realContentView?.layoutParams = FrameLayout.LayoutParams(
                widgetData.viewProperty!!.size[1], widgetData.viewProperty!!.size[3]
            )
        }

        //设置margin
        if (realContentView?.layoutParams is ViewGroup.MarginLayoutParams) {
            (realContentView?.layoutParams as ViewGroup.MarginLayoutParams).setMargins(
                widgetData.viewProperty!!.margin[0],
                widgetData.viewProperty!!.margin[1],
                widgetData.viewProperty!!.margin[2],
                widgetData.viewProperty!!.margin[3]
            );
        }
        //设置padding
        contentView!!.setPadding(
            widgetData.viewProperty!!.padding[0],
            widgetData.viewProperty!!.padding[1],
            widgetData.viewProperty!!.padding[2],
            widgetData.viewProperty!!.padding[3]
        )

        val leftTop = widgetData.viewProperty!!.radius[0]
        val rightTop = widgetData.viewProperty!!.radius[1]
        val rightBottom = widgetData.viewProperty!!.radius[2]
        val leftBottom = widgetData.viewProperty!!.radius[3]
        val strokeWidth = widgetData.viewProperty!!.stokeWidth
        val leftTopInner = leftTop - strokeWidth
        val rightTopInner = rightTop - strokeWidth
        val rightBottomInner = rightBottom - strokeWidth
        val leftBottomInner = leftBottom - strokeWidth


        var colorFilter: ColorMatrixColorFilter? = null
        if (ThemeColorUtil.SILENT) {
            val colorMatrix = ColorMatrix(
                floatArrayOf(
                    0.229f, 0.587f, 0.114f, 0f, 0f,
                    0.229f, 0.587f, 0.114f, 0f, 0f,
                    0.229f, 0.587f, 0.114f, 0f, 0f,
                    0f, 0f, 0f, 1f, 0f
                )
            )
            colorFilter = ColorMatrixColorFilter(colorMatrix)
        }

        realContentView!!.background = ShapeDrawable(object : RoundRectShape(
            floatArrayOf
                (
                leftTop, leftTop,
                rightTop, rightTop,
                rightBottom, rightBottom,
                leftBottom, leftBottom
            ),
            RectF(0F, 0F, 0F, 0F),
//            null
            floatArrayOf
                (
                leftTopInner, leftTopInner,
                rightTopInner, rightTopInner,
                rightBottomInner, rightBottomInner,
                leftBottomInner, leftBottomInner
//            0f,0f,0f,0f,0f,0f,0f,0f
            )
        ) {
            override fun draw(canvas: Canvas?, paint: Paint?) {
                super.draw(canvas, paint)
                paint?.color = widgetData.viewProperty!!.solidInt
                paint?.style = Paint.Style.FILL
                if (ThemeColorUtil.SILENT) {
                    paint?.colorFilter = colorFilter
                }
            }
        })
    }

    //更新视图参数
    open fun updateLayoutParam(viewGroup: ViewGroup.LayoutParams) {
    }

    //通过子组件数据，创建子组件
    open fun childMakeView() {
        if (widgetData.childData != null) {
            (contentView as? ViewGroup)?.removeAllViews()
            childList ?: run {
                childList = ArrayList()
            }
            widgetData.childData!!.forEach { childData ->
                //创建子组件
                val childWidget = WidgetFactory.createWidget(context, childData)
                childWidget?.let {
                    //设置父组件一定要在子组件之前
                    it.parentWidget = this@IWidget
                    //有了父视图才能操作子视图布局相关参数
                    it.makeWidget()
                    childList!!.add(it)
                }

            }
        }
    }

    //3.加载数据，两种（1，已经有数据，创建item，
    // 2，没有数据，请求数据，回调创建item）
    open fun loadData() {
        onLoadData()
        loadChild()
    }

    //所有加载当前widget的数据到视图的方法
    abstract fun onLoadData()

    open fun cancelLoad() {
        dataCaller?.cancelLoad()
    }

    //加载子视图
    protected open fun loadChild() {
        if (childList != null) {
            for (child in childList!!) {
                child.loadData()
            }
        }
    }

    open fun retrieveWidget(widgetId: String): IWidget? {
        if (widgetId == widgetData.widgetId) {
            return this
        } else {
            if (childList != null) {
                for (child in childList!!) {
                    val widget = child.retrieveWidget(widgetId)
                    if (widget != null) {
                        return widget
                    }
                }
            }
            return null
        }
    }

    //移除
    open fun removeWidget(widgetId: String): Boolean {
        if (widgetId == widgetData.widgetId) {
            return removeSelf()
        } else {
            if (childList != null) {
                for (child in childList!!) {
                    if (child.widgetData.widgetId == widgetId) {
                        return child.removeSelf()
                    }
                }
            }
            return false
        }
    }

    open fun removeSelf(): Boolean {
        //view remove
        detachFromParentContentView()
        //data remove
        resetData()
        return true
    }

    //从父视图移除数据，从父视图移除视图
    protected open fun detachFromParentContentView() {
        if (realContentView?.parent != null && parentWidget?.contentView == realContentView?.parent) {
            (parentWidget?.contentView as? ViewGroup)?.removeView(realContentView)
        }
    }

    //断开父组件的引用
    protected open fun resetData() {
        parentWidget?.childList?.remove(this)
        parentWidget = null
    }

    private fun removeAllChildWidget() {
        if (childList != null) {
            for (child in childList!!) {
                child.detachFromParentContentView()
                child.resetData()
            }
        }
    }

    override fun onViewAttachedToWindow(v: View?) {
        contentView?.let { RedDotUtil.registerMsg(it) }
    }

    override fun onViewDetachedFromWindow(v: View?) {
        cancelLoad()
        contentView?.let { RedDotUtil.unRegisterMsg(it) }
    }

    fun onResume() {
        childList?.forEach {
            it.onResume()
        }
    }

    fun onPause() {
        childList?.forEach {
            it.onPause()
        }
    }

    fun onDestroy() {
        childList?.forEach {
            it.onPause()
        }
    }

    //绑定到父组件的视图上
    open fun attachToParentWidget() {
        parentWidget ?: return
        contentView ?: return

        //核心就是将realContentView绑定到parentWidget的contentView上
        if (parentWidget!!.contentView is ViewGroup) {
            if (realContentView!!.parent != parentWidget!!.contentView) {
                ((parentWidget!!.contentView) as ViewGroup).addView(realContentView)
            }
        }
        //2遍历子组件并绑定
        childList?.forEach {
            it.attachToParentWidget()
        }
    }

    //绑定到视图上
    open fun attachToViewParent(viewGroup: ViewGroup) {
        contentView ?: return

        //如果父组件不为空
        parentWidget?.let {
            //如果viewGroup 是 父组件的 contentView
            if (viewGroup == it.contentView) {
                //如果已经添加了不再处理
                if (realContentView?.parent == it.contentView) {
                    return
                }
                //否则添加
                viewGroup.addView(realContentView)
            }
            //如果不是，就等于是替换父组件
            else {
                //先将父组件的所有数据移除
                it.removeAllChildWidget()
                //再将父组件的contentView替换
                it.contentView = viewGroup
                //再将本组件添加到父组件上
                it.childList?.add(this)
                it.childList?.forEach { item ->
                    item.attachToParentWidget()
                }
            }
            //最后添加到父组件的视图上
            return
        }

        //如果父组件是空的：
        viewGroup.addView(realContentView)
        //2遍历子组件并绑定
        childList?.forEach {
            it.attachToParentWidget()
        }
    }

    //更新红点
    fun updateReddot() {

    }
}